package com.github.bobjoy.java.spi.plugin;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;

public class PluginManager {

    private String plugins;

    private Map<String, PluginClassLoader> pluginMap = new HashMap<>();

    public PluginManager(String plugins) {
        this.plugins = plugins;
    }

    private void addLoader(String pluginName, PluginClassLoader loader) {
        this.pluginMap.put(pluginName, loader);
    }

    private PluginClassLoader getLoader(String pluginName) {
        return this.pluginMap.get(pluginName);
    }

    public void loadPlugin(String pluginName) {

        this.pluginMap.remove(pluginName);
        PluginClassLoader loader = new PluginClassLoader();
        String pluginurl = "jar:file:/D:/testclassloader/" + pluginName + ".jar!/";
        URL url = null;
        try {
            url = new URL(pluginurl);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        loader.addURLFile(url);
        addLoader(pluginName, loader);
        System.out.println("load " + pluginName + "  success");

    }

    public void unloadPlugin(String pluginName) {
        this.pluginMap.get(pluginName).unloadJarFiles();
        this.pluginMap.remove(pluginName);
    }

    /**
     * 读取插件实现列表
     */
    private List<String> getPluginUrls() {

        List<String> urls = new ArrayList<>();

        try (FileReader fr = new FileReader(plugins); BufferedReader reader = new BufferedReader(fr)) {

            String url;
            while ((url = reader.readLine()) != null) {
                if (url.startsWith("jar:file:/")) {
                    urls.add(url.trim());
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return urls;
    }

    public void loadPlugins() {
        try {

            // 循环加载插件 jar
            List<String> urls = getPluginUrls();

            System.out.println(">>>>>>>>>>>>>>>>>> load plugins started");
            for (String url : urls) {
                PluginClassLoader loader = new PluginClassLoader();
                loader.addURLFile(new URL(url));
                addLoader(url, loader);
            }
            System.out.println(">>>>>>>>>>>>>>>>>> load plugins finished");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void unloadPlugins() {
        List<String> urls = getPluginUrls();

        System.out.println(">>>>>>>>>>>>>>>>>> unload plugins stated");
        for (String url : urls) {
            PluginClassLoader loader = this.getLoader(url);
            if (loader != null) {
                loader.unloadJarFiles();
            }
            this.pluginMap.remove(url);
        }
        System.out.println(">>>>>>>>>>>>>>>>>> unload plugins finished");
    }

    public void executePlugin() {
        ServiceLoader<Plugin> loaders = ServiceLoader.load(Plugin.class);

        System.out.println(">>>>>>>>>>>>>>>>>> execute plugins stated");
        for (Plugin plugin : loaders) {
            System.out.println(plugin.sayHello());
        }
        System.out.println(">>>>>>>>>>>>>>>>>> execute plugins finished");
    }
}